HidService.java revision 37510150ee738ccfa5913f7120e28f25ae7768df
1/* 2 * Copyright (C) 2012 Google Inc. 3 */ 4 5package com.android.bluetooth.hid; 6 7import android.bluetooth.BluetoothDevice; 8import android.bluetooth.BluetoothInputDevice; 9import android.bluetooth.BluetoothProfile; 10import android.bluetooth.IBluetooth; 11import android.bluetooth.IBluetoothInputDevice; 12import android.content.Intent; 13import android.content.pm.PackageManager; 14import android.os.Bundle; 15import android.os.IBinder; 16import android.os.Handler; 17import android.os.Message; 18import android.os.RemoteException; 19import android.os.ServiceManager; 20import android.provider.Settings; 21import android.util.Log; 22import com.android.bluetooth.btservice.AdapterService; 23import com.android.bluetooth.btservice.ProfileService; 24import com.android.bluetooth.Utils; 25import java.util.ArrayList; 26import java.util.Collections; 27import java.util.HashMap; 28import java.util.List; 29import java.util.Map; 30 31 32/** 33 * Provides Bluetooth Hid Host profile, as a service in 34 * the Bluetooth application. 35 * @hide 36 */ 37public class HidService extends ProfileService { 38 private static final boolean DBG = true; 39 private static final String TAG = "HidService"; 40 41 private Map<BluetoothDevice, Integer> mInputDevices; 42 private boolean mNativeAvailable; 43 private static HidService sHidService; 44 private BluetoothDevice mTargetDevice = null; 45 46 private static final int MESSAGE_CONNECT = 1; 47 private static final int MESSAGE_DISCONNECT = 2; 48 private static final int MESSAGE_CONNECT_STATE_CHANGED = 3; 49 private static final int MESSAGE_GET_PROTOCOL_MODE = 4; 50 private static final int MESSAGE_VIRTUAL_UNPLUG = 5; 51 private static final int MESSAGE_ON_GET_PROTOCOL_MODE = 6; 52 private static final int MESSAGE_SET_PROTOCOL_MODE = 7; 53 private static final int MESSAGE_GET_REPORT = 8; 54 private static final int MESSAGE_ON_GET_REPORT = 9; 55 private static final int MESSAGE_SET_REPORT = 10; 56 private static final int MESSAGE_SEND_DATA = 11; 57 private static final int MESSAGE_ON_VIRTUAL_UNPLUG = 12; 58 59 static { 60 classInitNative(); 61 } 62 63 public String getName() { 64 return TAG; 65 } 66 67 public IProfileServiceBinder initBinder() { 68 return new BluetoothInputDeviceBinder(this); 69 } 70 71 protected boolean start() { 72 mInputDevices = Collections.synchronizedMap(new HashMap<BluetoothDevice, Integer>()); 73 initializeNative(); 74 mNativeAvailable=true; 75 setHidService(this); 76 return true; 77 } 78 79 protected boolean stop() { 80 if (DBG) log("Stopping Bluetooth HidService"); 81 return true; 82 } 83 84 protected boolean cleanup() { 85 if (mNativeAvailable) { 86 cleanupNative(); 87 mNativeAvailable=false; 88 } 89 90 if(mInputDevices != null) { 91 mInputDevices.clear(); 92 } 93 clearHidService(); 94 return true; 95 } 96 97 public static synchronized HidService getHidService(){ 98 if (sHidService != null && sHidService.isAvailable()) { 99 if (DBG) Log.d(TAG, "getHidService(): returning " + sHidService); 100 return sHidService; 101 } 102 if (DBG) { 103 if (sHidService == null) { 104 Log.d(TAG, "getHidService(): service is NULL"); 105 } else if (!(sHidService.isAvailable())) { 106 Log.d(TAG,"getHidService(): service is not available"); 107 } 108 } 109 return null; 110 } 111 112 private static synchronized void setHidService(HidService instance) { 113 if (instance != null && instance.isAvailable()) { 114 if (DBG) Log.d(TAG, "setHidService(): set to: " + sHidService); 115 sHidService = instance; 116 } else { 117 if (DBG) { 118 if (sHidService == null) { 119 Log.d(TAG, "setHidService(): service not available"); 120 } else if (!sHidService.isAvailable()) { 121 Log.d(TAG,"setHidService(): service is cleaning up"); 122 } 123 } 124 } 125 } 126 127 private static synchronized void clearHidService() { 128 sHidService = null; 129 } 130 131 132 private final Handler mHandler = new Handler() { 133 134 @Override 135 public void handleMessage(Message msg) { 136 switch (msg.what) { 137 case MESSAGE_CONNECT: 138 { 139 BluetoothDevice device = (BluetoothDevice) msg.obj; 140 if (!connectHidNative(Utils.getByteAddress(device)) ) { 141 broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTING); 142 broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED); 143 break; 144 } 145 mTargetDevice = device; 146 } 147 break; 148 case MESSAGE_DISCONNECT: 149 { 150 BluetoothDevice device = (BluetoothDevice) msg.obj; 151 if (!disconnectHidNative(Utils.getByteAddress(device)) ) { 152 broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTING); 153 broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED); 154 break; 155 } 156 } 157 break; 158 case MESSAGE_CONNECT_STATE_CHANGED: 159 { 160 BluetoothDevice device = getDevice((byte[]) msg.obj); 161 int halState = msg.arg1; 162 Integer prevStateInteger = mInputDevices.get(device); 163 int prevState = (prevStateInteger == null) ? 164 BluetoothInputDevice.STATE_DISCONNECTED :prevStateInteger; 165 if(DBG) Log.d(TAG, "MESSAGE_CONNECT_STATE_CHANGED newState:"+ 166 convertHalState(halState)+", prevState:"+prevState); 167 if(halState == CONN_STATE_CONNECTED && 168 prevState == BluetoothInputDevice.STATE_DISCONNECTED && 169 (!okToConnect(device))) { 170 Log.d(TAG,"Incoming HID connection rejected"); 171 disconnectHidNative(Utils.getByteAddress(device)); 172 } else { 173 broadcastConnectionState(device, convertHalState(halState)); 174 } 175 if (halState != CONN_STATE_CONNECTING) { 176 mTargetDevice = null; 177 } 178 else { 179 // CONN_STATE_CONNECTING is received only during 180 // local initiated connection. 181 mTargetDevice = device; 182 } 183 } 184 break; 185 case MESSAGE_GET_PROTOCOL_MODE: 186 { 187 BluetoothDevice device = (BluetoothDevice) msg.obj; 188 if(!getProtocolModeNative(Utils.getByteAddress(device)) ) { 189 Log.e(TAG, "Error: get protocol mode native returns false"); 190 } 191 } 192 break; 193 194 case MESSAGE_ON_GET_PROTOCOL_MODE: 195 { 196 BluetoothDevice device = getDevice((byte[]) msg.obj); 197 int protocolMode = msg.arg1; 198 broadcastProtocolMode(device, protocolMode); 199 } 200 break; 201 case MESSAGE_VIRTUAL_UNPLUG: 202 { 203 BluetoothDevice device = (BluetoothDevice) msg.obj; 204 if(!virtualUnPlugNative(Utils.getByteAddress(device))) { 205 Log.e(TAG, "Error: virtual unplug native returns false"); 206 } 207 } 208 break; 209 case MESSAGE_SET_PROTOCOL_MODE: 210 { 211 BluetoothDevice device = (BluetoothDevice) msg.obj; 212 byte protocolMode = (byte) msg.arg1; 213 log("sending set protocol mode(" + protocolMode + ")"); 214 if(!setProtocolModeNative(Utils.getByteAddress(device), protocolMode)) { 215 Log.e(TAG, "Error: set protocol mode native returns false"); 216 } 217 } 218 break; 219 case MESSAGE_GET_REPORT: 220 { 221 BluetoothDevice device = (BluetoothDevice) msg.obj; 222 Bundle data = msg.getData(); 223 byte reportType = data.getByte(BluetoothInputDevice.EXTRA_REPORT_TYPE); 224 byte reportId = data.getByte(BluetoothInputDevice.EXTRA_REPORT_ID); 225 int bufferSize = data.getInt(BluetoothInputDevice.EXTRA_REPORT_BUFFER_SIZE); 226 if(!getReportNative(Utils.getByteAddress(device), reportType, reportId, bufferSize)) { 227 Log.e(TAG, "Error: get report native returns false"); 228 } 229 } 230 break; 231 case MESSAGE_SET_REPORT: 232 { 233 BluetoothDevice device = (BluetoothDevice) msg.obj; 234 Bundle data = msg.getData(); 235 byte reportType = data.getByte(BluetoothInputDevice.EXTRA_REPORT_TYPE); 236 String report = data.getString(BluetoothInputDevice.EXTRA_REPORT); 237 if(!setReportNative(Utils.getByteAddress(device), reportType, report)) { 238 Log.e(TAG, "Error: set report native returns false"); 239 } 240 } 241 break; 242 case MESSAGE_SEND_DATA: 243 { 244 BluetoothDevice device = (BluetoothDevice) msg.obj; 245 Bundle data = msg.getData(); 246 String report = data.getString(BluetoothInputDevice.EXTRA_REPORT); 247 if(!sendDataNative(Utils.getByteAddress(device), report)) { 248 Log.e(TAG, "Error: send data native returns false"); 249 } 250 } 251 break; 252 case MESSAGE_ON_VIRTUAL_UNPLUG: 253 { 254 BluetoothDevice device = getDevice((byte[]) msg.obj); 255 int status = msg.arg1; 256 broadcastVirtualUnplugStatus(device, status); 257 } 258 break; 259 } 260 } 261 }; 262 263 /** 264 * Handlers for incoming service calls 265 */ 266 private static class BluetoothInputDeviceBinder extends IBluetoothInputDevice.Stub implements IProfileServiceBinder{ 267 private HidService mService; 268 public BluetoothInputDeviceBinder(HidService svc) { 269 mService = svc; 270 } 271 272 public boolean cleanup() { 273 mService = null; 274 return true; 275 } 276 277 private HidService getService() { 278 if (!Utils.checkCaller()) { 279 Log.w(TAG,"InputDevice call not allowed for non-active user"); 280 return null; 281 } 282 283 if (mService != null && mService.isAvailable()) { 284 return mService; 285 } 286 return null; 287 } 288 289 public boolean connect(BluetoothDevice device) { 290 HidService service = getService(); 291 if (service == null) return false; 292 return service.connect(device); 293 } 294 295 public boolean disconnect(BluetoothDevice device) { 296 HidService service = getService(); 297 if (service == null) return false; 298 return service.disconnect(device); 299 } 300 301 public int getConnectionState(BluetoothDevice device) { 302 HidService service = getService(); 303 if (service == null) return BluetoothInputDevice.STATE_DISCONNECTED; 304 return service.getConnectionState(device); 305 } 306 307 public List<BluetoothDevice> getConnectedDevices() { 308 return getDevicesMatchingConnectionStates( 309 new int[] {BluetoothProfile.STATE_CONNECTED}); 310 } 311 312 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 313 HidService service = getService(); 314 if (service == null) return new ArrayList<BluetoothDevice>(0); 315 return service.getDevicesMatchingConnectionStates(states); 316 } 317 318 public boolean setPriority(BluetoothDevice device, int priority) { 319 HidService service = getService(); 320 if (service == null) return false; 321 return service.setPriority(device, priority); 322 } 323 324 public int getPriority(BluetoothDevice device) { 325 HidService service = getService(); 326 if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED; 327 return service.getPriority(device); 328 } 329 330 /* The following APIs regarding test app for compliance */ 331 public boolean getProtocolMode(BluetoothDevice device) { 332 HidService service = getService(); 333 if (service == null) return false; 334 return service.getProtocolMode(device); 335 } 336 337 public boolean virtualUnplug(BluetoothDevice device) { 338 HidService service = getService(); 339 if (service == null) return false; 340 return service.virtualUnplug(device); 341 } 342 343 public boolean setProtocolMode(BluetoothDevice device, int protocolMode) { 344 HidService service = getService(); 345 if (service == null) return false; 346 return service.setProtocolMode(device, protocolMode); 347 } 348 349 public boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) { 350 HidService service = getService(); 351 if (service == null) return false; 352 return service.getReport(device, reportType, reportId, bufferSize) ; 353 } 354 355 public boolean setReport(BluetoothDevice device, byte reportType, String report) { 356 HidService service = getService(); 357 if (service == null) return false; 358 return service.setReport(device, reportType, report); 359 } 360 361 public boolean sendData(BluetoothDevice device, String report) { 362 HidService service = getService(); 363 if (service == null) return false; 364 return service.sendData(device, report); 365 } 366 }; 367 368 //APIs 369 boolean connect(BluetoothDevice device) { 370 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 371 if (getConnectionState(device) != BluetoothInputDevice.STATE_DISCONNECTED) { 372 Log.e(TAG, "Hid Device not disconnected: " + device); 373 return false; 374 } 375 if (getPriority(device) == BluetoothInputDevice.PRIORITY_OFF) { 376 Log.e(TAG, "Hid Device PRIORITY_OFF: " + device); 377 return false; 378 } 379 380 Message msg = mHandler.obtainMessage(MESSAGE_CONNECT, device); 381 mHandler.sendMessage(msg); 382 return true; 383 } 384 385 boolean disconnect(BluetoothDevice device) { 386 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 387 Message msg = mHandler.obtainMessage(MESSAGE_DISCONNECT,device); 388 mHandler.sendMessage(msg); 389 return true; 390 } 391 392 int getConnectionState(BluetoothDevice device) { 393 if (mInputDevices.get(device) == null) { 394 return BluetoothInputDevice.STATE_DISCONNECTED; 395 } 396 return mInputDevices.get(device); 397 } 398 399 List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 400 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 401 List<BluetoothDevice> inputDevices = new ArrayList<BluetoothDevice>(); 402 403 for (BluetoothDevice device: mInputDevices.keySet()) { 404 int inputDeviceState = getConnectionState(device); 405 for (int state : states) { 406 if (state == inputDeviceState) { 407 inputDevices.add(device); 408 break; 409 } 410 } 411 } 412 return inputDevices; 413 } 414 415 public boolean setPriority(BluetoothDevice device, int priority) { 416 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 417 "Need BLUETOOTH_ADMIN permission"); 418 Settings.Global.putInt(getContentResolver(), 419 Settings.Global.getBluetoothInputDevicePriorityKey(device.getAddress()), 420 priority); 421 if (DBG) Log.d(TAG,"Saved priority " + device + " = " + priority); 422 return true; 423 } 424 425 public int getPriority(BluetoothDevice device) { 426 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 427 "Need BLUETOOTH_ADMIN permission"); 428 int priority = Settings.Global.getInt(getContentResolver(), 429 Settings.Global.getBluetoothInputDevicePriorityKey(device.getAddress()), 430 BluetoothProfile.PRIORITY_UNDEFINED); 431 return priority; 432 } 433 434 /* The following APIs regarding test app for compliance */ 435 boolean getProtocolMode(BluetoothDevice device) { 436 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 437 "Need BLUETOOTH_ADMIN permission"); 438 int state = this.getConnectionState(device); 439 if (state != BluetoothInputDevice.STATE_CONNECTED) { 440 return false; 441 } 442 Message msg = mHandler.obtainMessage(MESSAGE_GET_PROTOCOL_MODE,device); 443 mHandler.sendMessage(msg); 444 return true; 445 /* String objectPath = getObjectPathFromAddress(device.getAddress()); 446 return getProtocolModeInputDeviceNative(objectPath);*/ 447 } 448 449 boolean virtualUnplug(BluetoothDevice device) { 450 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 451 "Need BLUETOOTH_ADMIN permission"); 452 int state = this.getConnectionState(device); 453 if (state != BluetoothInputDevice.STATE_CONNECTED) { 454 return false; 455 } 456 Message msg = mHandler.obtainMessage(MESSAGE_VIRTUAL_UNPLUG,device); 457 mHandler.sendMessage(msg); 458 return true; 459 } 460 461 boolean setProtocolMode(BluetoothDevice device, int protocolMode) { 462 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 463 "Need BLUETOOTH_ADMIN permission"); 464 int state = this.getConnectionState(device); 465 if (state != BluetoothInputDevice.STATE_CONNECTED) { 466 return false; 467 } 468 Message msg = mHandler.obtainMessage(MESSAGE_SET_PROTOCOL_MODE); 469 msg.obj = device; 470 msg.arg1 = protocolMode; 471 mHandler.sendMessage(msg); 472 return true ; 473 } 474 475 boolean getReport(BluetoothDevice device, byte reportType, byte reportId, int bufferSize) { 476 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 477 "Need BLUETOOTH_ADMIN permission"); 478 int state = this.getConnectionState(device); 479 if (state != BluetoothInputDevice.STATE_CONNECTED) { 480 return false; 481 } 482 Message msg = mHandler.obtainMessage(MESSAGE_GET_REPORT); 483 msg.obj = device; 484 Bundle data = new Bundle(); 485 data.putByte(BluetoothInputDevice.EXTRA_REPORT_TYPE, reportType); 486 data.putByte(BluetoothInputDevice.EXTRA_REPORT_ID, reportId); 487 data.putInt(BluetoothInputDevice.EXTRA_REPORT_BUFFER_SIZE, bufferSize); 488 msg.setData(data); 489 mHandler.sendMessage(msg); 490 return true ; 491 } 492 493 boolean setReport(BluetoothDevice device, byte reportType, String report) { 494 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 495 "Need BLUETOOTH_ADMIN permission"); 496 int state = this.getConnectionState(device); 497 if (state != BluetoothInputDevice.STATE_CONNECTED) { 498 return false; 499 } 500 Message msg = mHandler.obtainMessage(MESSAGE_SET_REPORT); 501 msg.obj = device; 502 Bundle data = new Bundle(); 503 data.putByte(BluetoothInputDevice.EXTRA_REPORT_TYPE, reportType); 504 data.putString(BluetoothInputDevice.EXTRA_REPORT, report); 505 msg.setData(data); 506 mHandler.sendMessage(msg); 507 return true ; 508 509 } 510 511 boolean sendData(BluetoothDevice device, String report) { 512 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 513 "Need BLUETOOTH_ADMIN permission"); 514 int state = this.getConnectionState(device); 515 if (state != BluetoothInputDevice.STATE_CONNECTED) { 516 return false; 517 } 518 519 return sendDataNative(Utils.getByteAddress(device), report); 520 /*Message msg = mHandler.obtainMessage(MESSAGE_SEND_DATA); 521 msg.obj = device; 522 Bundle data = new Bundle(); 523 data.putString(BluetoothInputDevice.EXTRA_REPORT, report); 524 msg.setData(data); 525 mHandler.sendMessage(msg); 526 return true ;*/ 527 } 528 529 private void onGetProtocolMode(byte[] address, int mode) { 530 Message msg = mHandler.obtainMessage(MESSAGE_ON_GET_PROTOCOL_MODE); 531 msg.obj = address; 532 msg.arg1 = mode; 533 mHandler.sendMessage(msg); 534 } 535 536 private void onVirtualUnplug(byte[] address, int status) { 537 Message msg = mHandler.obtainMessage(MESSAGE_ON_VIRTUAL_UNPLUG); 538 msg.obj = address; 539 msg.arg1 = status; 540 mHandler.sendMessage(msg); 541 } 542 543 private void onConnectStateChanged(byte[] address, int state) { 544 Message msg = mHandler.obtainMessage(MESSAGE_CONNECT_STATE_CHANGED); 545 msg.obj = address; 546 msg.arg1 = state; 547 mHandler.sendMessage(msg); 548 } 549 550 // This method does not check for error conditon (newState == prevState) 551 private void broadcastConnectionState(BluetoothDevice device, int newState) { 552 Integer prevStateInteger = mInputDevices.get(device); 553 int prevState = (prevStateInteger == null) ? BluetoothInputDevice.STATE_DISCONNECTED : 554 prevStateInteger; 555 if (prevState == newState) { 556 Log.w(TAG, "no state change: " + newState); 557 return; 558 } 559 mInputDevices.put(device, newState); 560 561 /* Notifying the connection state change of the profile before sending the intent for 562 connection state change, as it was causing a race condition, with the UI not being 563 updated with the correct connection state. */ 564 if (DBG) log("Connection state " + device + ": " + prevState + "->" + newState); 565 notifyProfileConnectionStateChanged(device, BluetoothProfile.INPUT_DEVICE, 566 newState, prevState); 567 Intent intent = new Intent(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED); 568 intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); 569 intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); 570 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 571 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 572 sendBroadcast(intent, BLUETOOTH_PERM); 573 } 574 575 private void broadcastProtocolMode(BluetoothDevice device, int protocolMode) { 576 Intent intent = new Intent(BluetoothInputDevice.ACTION_PROTOCOL_MODE_CHANGED); 577 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 578 intent.putExtra(BluetoothInputDevice.EXTRA_PROTOCOL_MODE, protocolMode); 579 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 580 sendBroadcast(intent, BLUETOOTH_PERM); 581 if (DBG) log("Protocol Mode (" + device + "): " + protocolMode); 582 } 583 584 private void broadcastVirtualUnplugStatus(BluetoothDevice device, int status) { 585 Intent intent = new Intent(BluetoothInputDevice.ACTION_VIRTUAL_UNPLUG_STATUS); 586 intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 587 intent.putExtra(BluetoothInputDevice.EXTRA_VIRTUAL_UNPLUG_STATUS, status); 588 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 589 sendBroadcast(intent, BLUETOOTH_PERM); 590 } 591 592 private boolean okToConnect(BluetoothDevice device) { 593 AdapterService adapterService = AdapterService.getAdapterService(); 594 //check if it is inbound connection in Quiet mode, priority and Bond status 595 //to decide if its ok to allow this connection 596 if((adapterService == null)|| 597 ((adapterService.isQuietModeEnabled()) &&(mTargetDevice == null)) || 598 (BluetoothProfile.PRIORITY_OFF == getPriority(device)) || 599 (device.getBondState() == BluetoothDevice.BOND_NONE)) 600 return false; 601 602 return true; 603 } 604 private static int convertHalState(int halState) { 605 switch (halState) { 606 case CONN_STATE_CONNECTED: 607 return BluetoothProfile.STATE_CONNECTED; 608 case CONN_STATE_CONNECTING: 609 return BluetoothProfile.STATE_CONNECTING; 610 case CONN_STATE_DISCONNECTED: 611 return BluetoothProfile.STATE_DISCONNECTED; 612 case CONN_STATE_DISCONNECTING: 613 return BluetoothProfile.STATE_DISCONNECTING; 614 default: 615 Log.e(TAG, "bad hid connection state: " + halState); 616 return BluetoothProfile.STATE_DISCONNECTED; 617 } 618 } 619 620 // Constants matching Hal header file bt_hh.h 621 // bthh_connection_state_t 622 private final static int CONN_STATE_CONNECTED = 0; 623 private final static int CONN_STATE_CONNECTING = 1; 624 private final static int CONN_STATE_DISCONNECTED = 2; 625 private final static int CONN_STATE_DISCONNECTING = 3; 626 627 private native static void classInitNative(); 628 private native void initializeNative(); 629 private native void cleanupNative(); 630 private native boolean connectHidNative(byte[] btAddress); 631 private native boolean disconnectHidNative(byte[] btAddress); 632 private native boolean getProtocolModeNative(byte[] btAddress); 633 private native boolean virtualUnPlugNative(byte[] btAddress); 634 private native boolean setProtocolModeNative(byte[] btAddress, byte protocolMode); 635 private native boolean getReportNative(byte[]btAddress, byte reportType, byte reportId, int bufferSize); 636 private native boolean setReportNative(byte[] btAddress, byte reportType, String report); 637 private native boolean sendDataNative(byte[] btAddress, String report); 638} 639