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 29e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Guptaimport java.util.Arrays; 30dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogovimport java.util.ArrayList; 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 1170afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov private 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 198e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta private ServiceConnection mConnection = new ServiceConnection() { 199e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 200e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public void onServiceConnected(ComponentName className, IBinder service) { 201e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG, "onServiceConnected()"); 202e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 2030afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov mService = IBluetoothInputHost.Stub.asInterface(service); 204e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 205e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mServiceListener != null) { 2060afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov mServiceListener.onServiceConnected(BluetoothProfile.INPUT_HOST, 2070afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov BluetoothInputHost.this); 208e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 209e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 210e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 211e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public void onServiceDisconnected(ComponentName className) { 212e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG, "onServiceDisconnected()"); 213e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 214e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mService = null; 215e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 216e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mServiceListener != null) { 2170afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov mServiceListener.onServiceDisconnected(BluetoothProfile.INPUT_HOST); 218e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 219e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 220e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta }; 221e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 2220afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov BluetoothInputHost(Context context, ServiceListener listener) { 2230afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov Log.v(TAG, "BluetoothInputHost"); 224e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 225e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mContext = context; 226e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mServiceListener = listener; 227e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mAdapter = BluetoothAdapter.getDefaultAdapter(); 228e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 229e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta IBluetoothManager mgr = mAdapter.getBluetoothManager(); 230e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mgr != null) { 231e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 232e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mgr.registerStateChangeCallback(mBluetoothStateChangeCallback); 233e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 234e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta e.printStackTrace(); 235e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 236e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 237e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 238e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta doBind(); 239e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 240e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 241e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean doBind() { 2420afe190af52d83c5e52fa994e53c48e33e8e3bf4Ivan Podogov Intent intent = new Intent(IBluetoothInputHost.class.getName()); 243e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 244e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta intent.setComponent(comp); 245e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0, 246e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta android.os.Process.myUserHandle())) { 247e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, "Could not bind to Bluetooth HID Device Service with " + intent); 248e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return false; 249e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 250e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.d(TAG, "Bound to HID Device Service"); 251e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return true; 252e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 253e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 254e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta void close() { 255e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "close()"); 256e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 257e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta IBluetoothManager mgr = mAdapter.getBluetoothManager(); 258e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mgr != null) { 259e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 260e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback); 261e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 262e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta e.printStackTrace(); 263e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 264e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 265e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 266e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta synchronized (mConnection) { 267e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 268e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mService = null; 269e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 270e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mContext.unbindService(mConnection); 271e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (IllegalArgumentException e) { 272e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG,"close: could not unbind HID Dev service: ", e); 273e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 274e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 275e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 276e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 277e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta mServiceListener = null; 278e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 279e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 280dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov /** 281dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * {@inheritDoc} 282dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov */ 283e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public List<BluetoothDevice> getConnectedDevices() { 284e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "getConnectedDevices()"); 285dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 286dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov if (mService != null) { 287dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov try { 288dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov return mService.getConnectedDevices(); 289dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } catch (RemoteException e) { 290dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.e(TAG, e.toString()); 291dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 292dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } else { 293dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.w(TAG, "Proxy not attached to service"); 294dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 295dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 296dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov return new ArrayList<BluetoothDevice>(); 297e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 298e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 299dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov /** 300dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * {@inheritDoc} 301dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov */ 302e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 303e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "getDevicesMatchingConnectionStates(): states=" + Arrays.toString(states)); 304dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 305dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov if (mService != null) { 306dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov try { 307dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov return mService.getDevicesMatchingConnectionStates(states); 308dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } catch (RemoteException e) { 309dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.e(TAG, e.toString()); 310dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 311dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } else { 312dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.w(TAG, "Proxy not attached to service"); 313dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 314dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 315dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov return new ArrayList<BluetoothDevice>(); 316e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 317e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 318dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov /** 319dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * {@inheritDoc} 320dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov */ 321e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public int getConnectionState(BluetoothDevice device) { 322dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "getConnectionState(): device=" + device); 323dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov 324dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov if (mService != null) { 325dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov try { 326dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov return mService.getConnectionState(device); 327dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } catch (RemoteException e) { 328dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.e(TAG, e.toString()); 329dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 330dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } else { 331dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.w(TAG, "Proxy not attached to service"); 332dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov } 333e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 334e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return STATE_DISCONNECTED; 335e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 336e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 337e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 338e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Registers application to be used for HID device. Connections to HID 339e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Device are only possible when application is registered. Only one 340e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * application can be registered at time. When no longer used, application 341e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * should be unregistered using 342e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * {@link #unregisterApp(BluetoothHidDeviceAppConfiguration)}. 343e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 344e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param sdp {@link BluetoothHidDeviceAppSdpSettings} object of 345e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * HID Device SDP record. 346e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param inQos {@link BluetoothHidDeviceAppQosSettings} object of 347e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Incoming QoS Settings. 348e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param outQos {@link BluetoothHidDeviceAppQosSettings} object of 349e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Outgoing QoS Settings. 350e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param callback {@link BluetoothHidDeviceCallback} object to which 351e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * callback messages will be sent. 352e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 353e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 354e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public boolean registerApp(BluetoothHidDeviceAppSdpSettings sdp, 355e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceAppQosSettings inQos, BluetoothHidDeviceAppQosSettings outQos, 356e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceCallback callback) { 357e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "registerApp(): sdp=" + sdp + " inQos=" + inQos + " outQos=" + outQos 358e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta + " callback=" + callback); 359e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 360e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 361e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 362e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (sdp == null || callback == null) { 363e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return false; 364e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 365e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 366e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 367e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 368e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceAppConfiguration config = 369e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta new BluetoothHidDeviceAppConfiguration(); 370e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta BluetoothHidDeviceCallbackWrapper cbw = 371e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta new BluetoothHidDeviceCallbackWrapper(callback); 372e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta result = mService.registerApp(config, sdp, inQos, outQos, cbw); 373e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 374e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 375e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 376e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 377e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 378e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 379e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 380e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 381e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 382e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 383e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 384e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Unregisters application. Active connection will be disconnected and no 385e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * new connections will be allowed until registered again using 386e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * {@link #registerApp(String, String, String, byte, byte[], BluetoothHidDeviceCallback)} 387e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 388e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param config {@link BluetoothHidDeviceAppConfiguration} object as 389e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * obtained from 390e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * {@link BluetoothHidDeviceCallback#onAppStatusChanged(BluetoothDevice, 391e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * BluetoothHidDeviceAppConfiguration, boolean)} 392e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 393e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 394e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 395e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta public boolean unregisterApp(BluetoothHidDeviceAppConfiguration config) { 396e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.v(TAG, "unregisterApp()"); 397e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 398e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 399e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 400e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 401e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 402e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta result = mService.unregisterApp(config); 403e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 404e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 405e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 406e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 407e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 408e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 409e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 410e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 411e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 412e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 413e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 414e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Sends report to remote host using interrupt channel. 415e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 416e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param id Report Id, as defined in descriptor. Can be 0 in case Report Id 417e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * are not defined in descriptor. 418e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param data Report data, not including Report Id. 419e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 420e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 421dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean sendReport(BluetoothDevice device, int id, byte[] data) { 422e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 423e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 424e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 425e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 426dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov result = mService.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 451e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 452e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 453dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov result = mService.replyReport(device, type, id, data); 454e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 455e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 456e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 457e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 458e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 459e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 460e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 461e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 462e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 463e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 464e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 465e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Sends error handshake message as reply for invalid SET_REPORT request 466dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov * from {@link BluetoothHidDeviceCallback#onSetReport(BluetoothDevice, byte, byte, byte[])}. 467e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 468e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @param error Error to be sent for SET_REPORT via HANDSHAKE. 469e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 470e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 471dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean reportError(BluetoothDevice device, byte error) { 472dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "reportError(): device=" + device + " error=" + error); 473e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 474e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 475e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 476e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 477e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 478dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov result = mService.reportError(device, error); 479e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 480e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 481e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 482e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 483e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 484e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 485e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 486e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 487e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 488e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 489e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 490e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Sends Virtual Cable Unplug to currently connected host. 491e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 492e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 493e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 494dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean unplug(BluetoothDevice device) { 495dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "unplug(): device=" + device); 496e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 497e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 498e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 499e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 500e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 501dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov result = mService.unplug(device); 502e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 503e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 504e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 505e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 506e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 507e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 508e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 509e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 510e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 511e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 512e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 513e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Initiates connection to host which currently has Virtual Cable 514e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * established with device. 515e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 516e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 517e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 518dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean connect(BluetoothDevice device) { 519dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "connect(): device=" + device); 520e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 521e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 522e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 523e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 524e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 525dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov result = mService.connect(device); 526e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 527e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 528e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 529e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 530e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 531e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 532e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 533e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 534e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 535e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 536e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta /** 537e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * Disconnects from currently connected host. 538e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * 539e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta * @return 540e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta */ 541dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov public boolean disconnect(BluetoothDevice device) { 542dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov Log.v(TAG, "disconnect(): device=" + device); 543e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 544e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta boolean result = false; 545e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 546e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta if (mService != null) { 547e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta try { 548dd87cd3bb611b7449edfa17d59d9b962784750eeIvan Podogov result = mService.disconnect(device); 549e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } catch (RemoteException e) { 550e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.e(TAG, e.toString()); 551e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 552e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } else { 553e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta Log.w(TAG, "Proxy not attached to service"); 554e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 555e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta 556e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta return result; 557e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta } 558e88fd4b5940a855e961cffa36e93f844a44cd2d4Hemant Gupta} 559