• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 android.util.Log;
20 
21 import com.android.internal.annotations.GuardedBy;
22 import com.android.internal.annotations.VisibleForTesting;
23 
24 /** Provides Bluetooth Hid Host profile, as a service in the Bluetooth application. */
25 public class HidHostNativeInterface {
26     private static final String TAG = HidHostNativeInterface.class.getSimpleName();
27 
28     private HidHostService mHidHostService;
29 
30     @GuardedBy("INSTANCE_LOCK")
31     private static HidHostNativeInterface sInstance;
32 
33     private static final Object INSTANCE_LOCK = new Object();
34 
getInstance()35     static HidHostNativeInterface getInstance() {
36         synchronized (INSTANCE_LOCK) {
37             if (sInstance == null) {
38                 sInstance = new HidHostNativeInterface();
39             }
40             return sInstance;
41         }
42     }
43 
44     /** Set singleton instance. */
45     @VisibleForTesting
setInstance(HidHostNativeInterface instance)46     public static void setInstance(HidHostNativeInterface instance) {
47         synchronized (INSTANCE_LOCK) {
48             sInstance = instance;
49         }
50     }
51 
init(HidHostService service)52     void init(HidHostService service) {
53         mHidHostService = service;
54         initializeNative();
55     }
56 
cleanup()57     void cleanup() {
58         cleanupNative();
59     }
60 
connectHid(byte[] address, int addressType, int transport)61     boolean connectHid(byte[] address, int addressType, int transport) {
62         return connectHidNative(address, addressType, transport);
63     }
64 
disconnectHid( byte[] address, int addressType, int transport, boolean reconnectAllowed)65     boolean disconnectHid(
66             byte[] address, int addressType, int transport, boolean reconnectAllowed) {
67         return disconnectHidNative(address, addressType, transport, reconnectAllowed);
68     }
69 
getProtocolMode(byte[] address, int addressType, int transport)70     boolean getProtocolMode(byte[] address, int addressType, int transport) {
71         return getProtocolModeNative(address, addressType, transport);
72     }
73 
virtualUnPlug(byte[] address, int addressType, int transport)74     boolean virtualUnPlug(byte[] address, int addressType, int transport) {
75         return virtualUnPlugNative(address, addressType, transport);
76     }
77 
setProtocolMode(byte[] address, int addressType, int transport, byte protocolMode)78     boolean setProtocolMode(byte[] address, int addressType, int transport, byte protocolMode) {
79         return setProtocolModeNative(address, addressType, transport, protocolMode);
80     }
81 
getReport( byte[] address, int addressType, int transport, byte reportType, byte reportId, int bufferSize)82     boolean getReport(
83             byte[] address,
84             int addressType,
85             int transport,
86             byte reportType,
87             byte reportId,
88             int bufferSize) {
89         return getReportNative(address, addressType, transport, reportType, reportId, bufferSize);
90     }
91 
setReport( byte[] address, int addressType, int transport, byte reportType, String report)92     boolean setReport(
93             byte[] address, int addressType, int transport, byte reportType, String report) {
94         return setReportNative(address, addressType, transport, reportType, report);
95     }
96 
sendData(byte[] address, int addressType, int transport, String report)97     boolean sendData(byte[] address, int addressType, int transport, String report) {
98         return sendDataNative(address, addressType, transport, report);
99     }
100 
setIdleTime(byte[] address, int addressType, int transport, byte idleTime)101     boolean setIdleTime(byte[] address, int addressType, int transport, byte idleTime) {
102         return setIdleTimeNative(address, addressType, transport, idleTime);
103     }
104 
getIdleTime(byte[] address, int addressType, int transport)105     boolean getIdleTime(byte[] address, int addressType, int transport) {
106         return getIdleTimeNative(address, addressType, transport);
107     }
108 
convertHalState(int halState)109     private static int convertHalState(int halState) {
110         switch (halState) {
111             case CONN_STATE_CONNECTED:
112                 return HidHostService.STATE_CONNECTED;
113             case CONN_STATE_CONNECTING:
114                 return HidHostService.STATE_CONNECTING;
115             case CONN_STATE_DISCONNECTED:
116                 return HidHostService.STATE_DISCONNECTED;
117             case CONN_STATE_DISCONNECTING:
118                 return HidHostService.STATE_DISCONNECTING;
119             case CONN_STATE_ACCEPTING:
120                 return HidHostService.STATE_ACCEPTING;
121             default:
122                 Log.e(TAG, "bad hid connection state: " + halState);
123                 return HidHostService.STATE_DISCONNECTED;
124         }
125     }
126 
127     /**********************************************************************************************/
128     /*********************************** callbacks from native ************************************/
129     /**********************************************************************************************/
130 
onConnectStateChanged(byte[] address, int addressType, int transport, int state)131     private void onConnectStateChanged(byte[] address, int addressType, int transport, int state) {
132         Log.d(TAG, "onConnectStateChanged: state=" + state);
133         mHidHostService.onConnectStateChanged(
134                 address, addressType, transport, convertHalState(state));
135     }
136 
onGetProtocolMode(byte[] address, int addressType, int transport, int mode)137     private void onGetProtocolMode(byte[] address, int addressType, int transport, int mode) {
138         Log.d(TAG, "onGetProtocolMode()");
139         mHidHostService.onGetProtocolMode(address, addressType, transport, mode);
140     }
141 
onGetReport( byte[] address, int addressType, int transport, byte[] report, int rptSize)142     private void onGetReport(
143             byte[] address, int addressType, int transport, byte[] report, int rptSize) {
144         Log.d(TAG, "onGetReport()");
145         mHidHostService.onGetReport(address, addressType, transport, report, rptSize);
146     }
147 
onHandshake(byte[] address, int addressType, int transport, int status)148     private void onHandshake(byte[] address, int addressType, int transport, int status) {
149         Log.d(TAG, "onHandshake: status=" + status);
150         mHidHostService.onHandshake(address, addressType, transport, status);
151     }
152 
onVirtualUnplug(byte[] address, int addressType, int transport, int status)153     private void onVirtualUnplug(byte[] address, int addressType, int transport, int status) {
154         Log.d(TAG, "onVirtualUnplug: status=" + status);
155         mHidHostService.onVirtualUnplug(address, addressType, transport, status);
156     }
157 
onGetIdleTime(byte[] address, int addressType, int transport, int idleTime)158     private void onGetIdleTime(byte[] address, int addressType, int transport, int idleTime) {
159         Log.d(TAG, "onGetIdleTime()");
160         mHidHostService.onGetIdleTime(address, addressType, transport, idleTime);
161     }
162 
163     /**********************************************************************************************/
164     /******************************************* native *******************************************/
165     /**********************************************************************************************/
166 
167     // Constants matching Hal header file bt_hh.h
168     // bthh_connection_state_t
169     private static final int CONN_STATE_CONNECTED = 0;
170 
171     private static final int CONN_STATE_CONNECTING = 1;
172     private static final int CONN_STATE_DISCONNECTED = 2;
173     private static final int CONN_STATE_DISCONNECTING = 3;
174     private static final int CONN_STATE_ACCEPTING = 4;
175 
initializeNative()176     private native void initializeNative();
177 
cleanupNative()178     private native void cleanupNative();
179 
connectHidNative(byte[] btAddress, int addressType, int transport)180     private native boolean connectHidNative(byte[] btAddress, int addressType, int transport);
181 
disconnectHidNative( byte[] btAddress, int addressType, int transport, boolean reconnectAllowed)182     private native boolean disconnectHidNative(
183             byte[] btAddress, int addressType, int transport, boolean reconnectAllowed);
184 
getProtocolModeNative(byte[] btAddress, int addressType, int transport)185     private native boolean getProtocolModeNative(byte[] btAddress, int addressType, int transport);
186 
virtualUnPlugNative(byte[] btAddress, int addressType, int transport)187     private native boolean virtualUnPlugNative(byte[] btAddress, int addressType, int transport);
188 
setProtocolModeNative( byte[] btAddress, int addressType, int transport, byte protocolMode)189     private native boolean setProtocolModeNative(
190             byte[] btAddress, int addressType, int transport, byte protocolMode);
191 
getReportNative( byte[] btAddress, int addressType, int transport, byte reportType, byte reportId, int bufferSize)192     private native boolean getReportNative(
193             byte[] btAddress,
194             int addressType,
195             int transport,
196             byte reportType,
197             byte reportId,
198             int bufferSize);
199 
setReportNative( byte[] btAddress, int addressType, int transport, byte reportType, String report)200     private native boolean setReportNative(
201             byte[] btAddress, int addressType, int transport, byte reportType, String report);
202 
sendDataNative( byte[] btAddress, int addressType, int transport, String report)203     private native boolean sendDataNative(
204             byte[] btAddress, int addressType, int transport, String report);
205 
setIdleTimeNative( byte[] btAddress, int addressType, int transport, byte idleTime)206     private native boolean setIdleTimeNative(
207             byte[] btAddress, int addressType, int transport, byte idleTime);
208 
getIdleTimeNative(byte[] btAddress, int addressType, int transport)209     private native boolean getIdleTimeNative(byte[] btAddress, int addressType, int transport);
210 }
211