• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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