1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.bluetooth.hid; 18 19 import static android.bluetooth.BluetoothProfile.STATE_CONNECTED; 20 import static android.bluetooth.BluetoothProfile.STATE_CONNECTING; 21 import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED; 22 import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING; 23 24 import android.util.Log; 25 26 import com.android.internal.annotations.GuardedBy; 27 import com.android.internal.annotations.VisibleForTesting; 28 29 /** Provides Bluetooth Hid Host profile, as a service in the Bluetooth application. */ 30 public class HidHostNativeInterface { 31 private static final String TAG = HidHostNativeInterface.class.getSimpleName(); 32 33 private HidHostService mHidHostService; 34 35 @GuardedBy("INSTANCE_LOCK") 36 private static HidHostNativeInterface sInstance; 37 38 private static final Object INSTANCE_LOCK = new Object(); 39 getInstance()40 static HidHostNativeInterface getInstance() { 41 synchronized (INSTANCE_LOCK) { 42 if (sInstance == null) { 43 sInstance = new HidHostNativeInterface(); 44 } 45 return sInstance; 46 } 47 } 48 49 /** Set singleton instance. */ 50 @VisibleForTesting setInstance(HidHostNativeInterface instance)51 public static void setInstance(HidHostNativeInterface instance) { 52 synchronized (INSTANCE_LOCK) { 53 sInstance = instance; 54 } 55 } 56 init(HidHostService service)57 void init(HidHostService service) { 58 mHidHostService = service; 59 initializeNative(); 60 } 61 cleanup()62 void cleanup() { 63 cleanupNative(); 64 } 65 connectHid(byte[] address, int addressType, int transport)66 boolean connectHid(byte[] address, int addressType, int transport) { 67 return connectHidNative(address, addressType, transport); 68 } 69 disconnectHid( byte[] address, int addressType, int transport, boolean reconnectAllowed)70 boolean disconnectHid( 71 byte[] address, int addressType, int transport, boolean reconnectAllowed) { 72 return disconnectHidNative(address, addressType, transport, reconnectAllowed); 73 } 74 getProtocolMode(byte[] address, int addressType, int transport)75 boolean getProtocolMode(byte[] address, int addressType, int transport) { 76 return getProtocolModeNative(address, addressType, transport); 77 } 78 virtualUnPlug(byte[] address, int addressType, int transport)79 boolean virtualUnPlug(byte[] address, int addressType, int transport) { 80 return virtualUnPlugNative(address, addressType, transport); 81 } 82 setProtocolMode(byte[] address, int addressType, int transport, byte protocolMode)83 boolean setProtocolMode(byte[] address, int addressType, int transport, byte protocolMode) { 84 return setProtocolModeNative(address, addressType, transport, protocolMode); 85 } 86 getReport( byte[] address, int addressType, int transport, byte reportType, byte reportId, int bufferSize)87 boolean getReport( 88 byte[] address, 89 int addressType, 90 int transport, 91 byte reportType, 92 byte reportId, 93 int bufferSize) { 94 return getReportNative(address, addressType, transport, reportType, reportId, bufferSize); 95 } 96 setReport( byte[] address, int addressType, int transport, byte reportType, String report)97 boolean setReport( 98 byte[] address, int addressType, int transport, byte reportType, String report) { 99 return setReportNative(address, addressType, transport, reportType, report); 100 } 101 sendData(byte[] address, int addressType, int transport, String report)102 boolean sendData(byte[] address, int addressType, int transport, String report) { 103 return sendDataNative(address, addressType, transport, report); 104 } 105 setIdleTime(byte[] address, int addressType, int transport, byte idleTime)106 boolean setIdleTime(byte[] address, int addressType, int transport, byte idleTime) { 107 return setIdleTimeNative(address, addressType, transport, idleTime); 108 } 109 getIdleTime(byte[] address, int addressType, int transport)110 boolean getIdleTime(byte[] address, int addressType, int transport) { 111 return getIdleTimeNative(address, addressType, transport); 112 } 113 convertHalState(int halState)114 private static int convertHalState(int halState) { 115 switch (halState) { 116 case CONN_STATE_CONNECTED: 117 return STATE_CONNECTED; 118 case CONN_STATE_CONNECTING: 119 return STATE_CONNECTING; 120 case CONN_STATE_DISCONNECTED: 121 return STATE_DISCONNECTED; 122 case CONN_STATE_DISCONNECTING: 123 return STATE_DISCONNECTING; 124 case CONN_STATE_ACCEPTING: 125 return HidHostService.STATE_ACCEPTING; 126 default: 127 Log.e(TAG, "bad hid connection state: " + halState); 128 return STATE_DISCONNECTED; 129 } 130 } 131 132 /**********************************************************************************************/ 133 /*********************************** callbacks from native ************************************/ 134 /**********************************************************************************************/ 135 onConnectStateChanged(byte[] address, int addressType, int transport, int state)136 private void onConnectStateChanged(byte[] address, int addressType, int transport, int state) { 137 Log.d(TAG, "onConnectStateChanged: state=" + state); 138 mHidHostService.onConnectStateChanged( 139 address, addressType, transport, convertHalState(state)); 140 } 141 onGetProtocolMode(byte[] address, int addressType, int transport, int mode)142 private void onGetProtocolMode(byte[] address, int addressType, int transport, int mode) { 143 Log.d(TAG, "onGetProtocolMode()"); 144 mHidHostService.onGetProtocolMode(address, addressType, transport, mode); 145 } 146 onGetReport( byte[] address, int addressType, int transport, byte[] report, int rptSize)147 private void onGetReport( 148 byte[] address, int addressType, int transport, byte[] report, int rptSize) { 149 Log.d(TAG, "onGetReport()"); 150 mHidHostService.onGetReport(address, addressType, transport, report, rptSize); 151 } 152 onHandshake(byte[] address, int addressType, int transport, int status)153 private void onHandshake(byte[] address, int addressType, int transport, int status) { 154 Log.d(TAG, "onHandshake: status=" + status); 155 mHidHostService.onHandshake(address, addressType, transport, status); 156 } 157 onVirtualUnplug(byte[] address, int addressType, int transport, int status)158 private void onVirtualUnplug(byte[] address, int addressType, int transport, int status) { 159 Log.d(TAG, "onVirtualUnplug: status=" + status); 160 mHidHostService.onVirtualUnplug(address, addressType, transport, status); 161 } 162 onGetIdleTime(byte[] address, int addressType, int transport, int idleTime)163 private void onGetIdleTime(byte[] address, int addressType, int transport, int idleTime) { 164 Log.d(TAG, "onGetIdleTime()"); 165 mHidHostService.onGetIdleTime(address, addressType, transport, idleTime); 166 } 167 168 /**********************************************************************************************/ 169 /******************************************* native *******************************************/ 170 /**********************************************************************************************/ 171 172 // Constants matching Hal header file bt_hh.h 173 // bthh_connection_state_t 174 private static final int CONN_STATE_CONNECTED = 0; 175 176 private static final int CONN_STATE_CONNECTING = 1; 177 private static final int CONN_STATE_DISCONNECTED = 2; 178 private static final int CONN_STATE_DISCONNECTING = 3; 179 private static final int CONN_STATE_ACCEPTING = 4; 180 initializeNative()181 private native void initializeNative(); 182 cleanupNative()183 private native void cleanupNative(); 184 connectHidNative(byte[] btAddress, int addressType, int transport)185 private native boolean connectHidNative(byte[] btAddress, int addressType, int transport); 186 disconnectHidNative( byte[] btAddress, int addressType, int transport, boolean reconnectAllowed)187 private native boolean disconnectHidNative( 188 byte[] btAddress, int addressType, int transport, boolean reconnectAllowed); 189 getProtocolModeNative(byte[] btAddress, int addressType, int transport)190 private native boolean getProtocolModeNative(byte[] btAddress, int addressType, int transport); 191 virtualUnPlugNative(byte[] btAddress, int addressType, int transport)192 private native boolean virtualUnPlugNative(byte[] btAddress, int addressType, int transport); 193 setProtocolModeNative( byte[] btAddress, int addressType, int transport, byte protocolMode)194 private native boolean setProtocolModeNative( 195 byte[] btAddress, int addressType, int transport, byte protocolMode); 196 getReportNative( byte[] btAddress, int addressType, int transport, byte reportType, byte reportId, int bufferSize)197 private native boolean getReportNative( 198 byte[] btAddress, 199 int addressType, 200 int transport, 201 byte reportType, 202 byte reportId, 203 int bufferSize); 204 setReportNative( byte[] btAddress, int addressType, int transport, byte reportType, String report)205 private native boolean setReportNative( 206 byte[] btAddress, int addressType, int transport, byte reportType, String report); 207 sendDataNative( byte[] btAddress, int addressType, int transport, String report)208 private native boolean sendDataNative( 209 byte[] btAddress, int addressType, int transport, String report); 210 setIdleTimeNative( byte[] btAddress, int addressType, int transport, byte idleTime)211 private native boolean setIdleTimeNative( 212 byte[] btAddress, int addressType, int transport, byte idleTime); 213 getIdleTimeNative(byte[] btAddress, int addressType, int transport)214 private native boolean getIdleTimeNative(byte[] btAddress, int addressType, int transport); 215 } 216